package com.qys.livesMall.shop.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.common.utils.DateUtils;
import com.qys.livesMall.common.utils.TimestampUtil;
import com.qys.livesMall.kafka.entity.shop.ShopBrowseRecord;
import com.qys.livesMall.shop.mapper.ShopStatisticsMapper;
import com.qys.livesMall.shop.modal.dto.PurchaseData;
import com.qys.livesMall.shop.modal.dto.SalesData;
import com.qys.livesMall.shop.modal.dto.ShopOrderData;
import com.qys.livesMall.shop.modal.dto.UserData;
import com.qys.livesMall.shop.service.ShopStatisticsService;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.util.Map;

/**
 * @packageName:
 * @className:ShopStatisticsServiceImpl
 * @Description:
 * @author:guomx
 * @date:2023/7/1215:17
 */
@Service
public class ShopStatisticsServiceImpl implements ShopStatisticsService {
    @Resource
    private ShopStatisticsMapper mapper;
    @Resource
    private MongoTemplate mongoTemplate;
    //销售数据
    @Override
    public R<SalesData> salesDataStatistics(String shopId) {
        SalesData salesData = new SalesData();
        Map<String, BigDecimal> dayMoney = mapper.queryDayMoney(shopId);
        Map<String, Object> week = mapper.queryWeek(shopId);
        Map<String, Object> month = mapper.queryMonth(shopId);
        Map<String, Object> sum = mapper.sumOrder(shopId);
        if (ObjectUtils.isNotEmpty(week)){
            if (ObjectUtils.isNotEmpty(week.get("weekly_sales"))) {
                salesData.setWeeklySales(new BigDecimal(week.get("weekly_sales").toString()));
            }
            if (ObjectUtils.isNotEmpty(week.get("weekly_growth_rate"))){
                salesData.setWeeklyGrowthRate(Double.valueOf(week.get("weekly_growth_rate").toString()));
            }
        }
        if (ObjectUtils.isNotEmpty(month)){
            if (ObjectUtils.isNotEmpty(month.get("monthly_sales"))) {
                salesData.setMonthlySales(new BigDecimal(month.get("monthly_sales").toString()));
            }
            if (ObjectUtils.isNotEmpty(month.get("monthly_growth_rate"))){
                salesData.setMonthlyGrowthRate(Double.valueOf(month.get("monthly_growth_rate").toString()));
            }
        }
        if(ObjectUtils.isNotEmpty(dayMoney)){
            salesData.setDailySales(dayMoney.get("daily_sales"));
        }
       if(ObjectUtils.isNotEmpty(sum)){
           if (ObjectUtils.isNotEmpty(sum.get("total_sales"))){
               salesData.setTotalSales(new BigDecimal(sum.get("total_sales").toString()));
           }
           if (ObjectUtils.isNotEmpty(sum.get("total_orders"))){
               salesData.setTotalOrders(Long.valueOf(sum.get("total_orders").toString()));
           }
       }

        return R.ok(salesData);
    }
    //用户数据
    @Override
    public R<UserData> userDataStatistics(String shopId) {
        UserData userData = new UserData();
        Map<String, Long> map = TimestampUtil.getCurrentWeekTimeFrame();
        Long weekStart = map.get("startTime");
        Instant instant = Instant.ofEpochMilli(weekStart);
        LocalDateTime weekStartTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        Long weekEnd = map.get("endTime");        //1、创建Criteria对象，并设置查询条件
        Instant instantend = Instant.ofEpochMilli(weekEnd);
        LocalDateTime weekEndtTime = LocalDateTime.ofInstant(instantend, ZoneId.systemDefault());
        Criteria criteria = Criteria
                .where("shopId").is(Long.valueOf(shopId))
                .andOperator(
                        new Criteria().and("browseDate").gte(weekStartTime),
                        new Criteria().and("browseDate").lte(weekEndtTime));
        Query query = new Query(criteria)
                .with(Sort.by(Sort.Order.desc("browseDate")));
        long weekUser = mongoTemplate.count(query, ShopBrowseRecord.class);
        Criteria mcriteria = Criteria
                .where("shopId").is(Long.valueOf(shopId))
                .andOperator(
                        new Criteria().and("browseDate").gte(DateUtils.startOfTheMouth()),
                        new Criteria().and("browseDate").lte(DateUtils.endOfTheMouth()));
        query=new Query(mcriteria).with(Sort.by(Sort.Order.desc("browseDate")));
        long mouthUser = mongoTemplate.count(query, ShopBrowseRecord.class);
        Criteria dcriteria = Criteria
                .where("shopId").is(Long.valueOf(shopId))
                .andOperator(
                        new Criteria().and("browseDate").gte(DateUtils.of(LocalDate.now(), LocalTime.MIN)),
                        new Criteria().and("browseDate").lte(DateUtils.of(LocalDate.now(), LocalTime.MAX)));
        query=new Query(dcriteria).with(Sort.by(Sort.Order.desc("browseDate")));
        long dayUser = mongoTemplate.count(query, ShopBrowseRecord.class);
        Map<String, Object> sum = mapper.sumOrder(shopId);
        BigDecimal apa=BigDecimal.ZERO;
        if (ObjectUtils.isNotEmpty(sum.get("total_sales"))){
            BigDecimal totalSales = new BigDecimal(sum.get("total_sales").toString());
            Long totalOrders = Long.valueOf(sum.get("total_orders").toString());
            apa = totalSales.divide(new BigDecimal(totalOrders), RoundingMode.DOWN);

        }
        Map<String, Object> repeat = mapper.queryRepeat(shopId);
        if (ObjectUtils.isNotEmpty(dayUser)){
            userData.setDayUser(dayUser);
        }
        if (ObjectUtils.isNotEmpty(weekUser)){
            userData.setWeekUser(weekUser);
        }
        if (ObjectUtils.isNotEmpty(mouthUser)){
            userData.setMouthUser(mouthUser);
        }
        userData.setApa(apa);
        if (ObjectUtils.isNotEmpty(repeat.get("repeat_rate"))){
            Double repeatRate = Double.valueOf(repeat.get("repeat_rate").toString());
            userData.setRepeatRate(repeatRate);
        }
        return R.ok(userData);
    }

    @Override
    public R<PurchaseData> purchaseDataStatistics(String shopId) {
        PurchaseData purchaseData = new PurchaseData();
        Map<String, Object> pw = mapper.queryPurchaseWeek(shopId);
        Map<String, Object> pm = mapper.queryPurchaseMonth(shopId);
        Map<String, Object> pc = mapper.purchaseCategories(shopId);
        Map<String, Object> apq = mapper.averagePurchaseQuantity(shopId);
        if (ObjectUtils.isNotEmpty(pw)){
            if (ObjectUtils.isNotEmpty(pw.get("weekly_purchase_count"))){
                purchaseData.setWeeklyPurchase(pw.get("weekly_purchase_count").toString());
            }
        }
        if (ObjectUtils.isNotEmpty(pc)){
            if (ObjectUtils.isNotEmpty(pc.get("purchase_categories"))){
                purchaseData.setPurchaseCategories(pc.get("purchase_categories").toString());
            }
        }
        if (ObjectUtils.isNotEmpty(apq)){
            if (ObjectUtils.isNotEmpty(apq.get("average_purchase_quantity"))){
                purchaseData.setAveragePurchaseQuantity(apq.get("average_purchase_quantity").toString());
            }
        }
        if (ObjectUtils.isNotEmpty(pm)) {
            if (ObjectUtils.isNotEmpty(pm.get("monthly_purchase_count"))) {
                purchaseData.setMonthlyPurchase(pm.get("monthly_purchase_count").toString());
            }
        }
        return R.ok(purchaseData);
    }

    @Override
    public R<ShopOrderData> shopOrderDataStatistics(String shopId) {
        ShopOrderData orderData = new ShopOrderData();
        Long todayNew = mapper.todayNew(shopId);
        if (ObjectUtils.isNotEmpty(todayNew)){
            orderData.setTodayNew(todayNew.toString());
        }
        Long yesterdayNew = mapper.yesterdayNew(shopId);
        if (ObjectUtils.isNotEmpty(yesterdayNew)){
            orderData.setYesterdayNew(yesterdayNew.toString());
        }
        Long todayTotal = mapper.todayTotal(shopId);
        if (ObjectUtils.isNotEmpty(todayTotal)){
            orderData.setTodayTotal(todayTotal.toString());
        }
        Long yesterdayTotal = mapper.yesterdayTotal(shopId);
        if (ObjectUtils.isNotEmpty(yesterdayTotal)){
            orderData.setYesterdayTotal(yesterdayTotal.toString());
        }
        return R.ok(orderData);
    }

}
